/**
 *  @file
 *  @brief   桌子模型，使用梁模拟桌腿， RBAR1使得桌面固定?
 *  @author  huangjingxiang
 *  @date    2024.05.12
 *  @version  v1.0
 *  @par Copyright(c):  ShenGong  Simulation corporation
 */

#pragma once
#include "DataStructure/Input/Element/CBARData.h"
#include "DataStructure/Input/Constraint/RBAR1Data.h"
#include "DBManager/Database/DatabaseFactory.h"
#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Element/IElementService.h"
#include "DBManager/IService/Input/Constraint/IRBAR1Service.h"
#include "DBManager/IService/Input/Node/INodeService.h"

using SG::DataStructure::FEM::DOFDirections;
using namespace SG::DBManager;
extern std::shared_ptr<DBServiceFactory> DB_SERVICEFACTORY;

/** @brief 简单桌子模型
 *
 * 使用四根梁模拟桌腿， 而桌面顶点使用RBar1 约束单元的线自由度
 */
class Desk_RBAR1Surface
{
  public:
    Desk_RBAR1Surface ()
    {
        DB_SERVICEFACTORY->ClearDatabase ();
        Input (DB_SERVICEFACTORY);
    }

    /// @brief 写入模型数据
    void               Input (const DBServiceFactorySP dbServiceFactory);
    DBServiceFactorySP GetModel ()
    {
        return DB_SERVICEFACTORY;
    }
};

void Desk_RBAR1Surface::Input (const DBServiceFactorySP dbServiceFactory)
{
    // 节点写入
    {
        SG::DataStructure::FEM::NodeData node;
        node.m_id   = 1;
        node.m_x[0] = 0.0;
        node.m_x[1] = 0.0;
        node.m_x[2] = 0.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
        node.m_id   = 2;
        node.m_x[0] = 1.0;
        node.m_x[1] = 0.0;
        node.m_x[2] = 0.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
        node.m_id   = 3;
        node.m_x[0] = 1.0;
        node.m_x[1] = 1.0;
        node.m_x[2] = 0.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
        node.m_id   = 4;
        node.m_x[0] = 0.0;
        node.m_x[1] = 1.0;
        node.m_x[2] = 0.0;
        dbServiceFactory->get<INodeService> ()->Add (node);

        node.m_id   = 5;
        node.m_x[0] = 0.0;
        node.m_x[1] = 0.0;
        node.m_x[2] = 1.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
        node.m_id   = 6;
        node.m_x[0] = 1.0;
        node.m_x[1] = 0.0;
        node.m_x[2] = 1.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
        node.m_id   = 7;
        node.m_x[0] = 1.0;
        node.m_x[1] = 1.0;
        node.m_x[2] = 1.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
        node.m_id   = 8;
        node.m_x[0] = 0.0;
        node.m_x[1] = 1.0;
        node.m_x[2] = 1.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
    }
    // 截面属性写入
    {
        // SG::DataStructure::FEM::PRODData prod;
        // prod.m_id = 1;
        // prod.m_mId = 1;
        // prod.m_area = 0.5;
        // dbServiceFactory -> get<PRODService>()->Add (prod);
    }
    // 写入单元
    {
        SG::DataStructure::FEM::CBARData beam;
        beam.m_id   = 1;
        beam.m_g[0] = 1;
        beam.m_g[1] = 5;
        dbServiceFactory->get<IElementService> ()->Add (beam);

        beam.m_id   = 2;
        beam.m_g[0] = 2;
        beam.m_g[1] = 6;
        dbServiceFactory->get<IElementService> ()->Add (beam);

        beam.m_id   = 3;
        beam.m_g[0] = 3;
        beam.m_g[1] = 7;
        dbServiceFactory->get<IElementService> ()->Add (beam);

        beam.m_id   = 4;
        beam.m_g[0] = 4;
        beam.m_g[1] = 8;
        dbServiceFactory->get<IElementService> ()->Add (beam);
    }
    // 桌面使用RBAR1 约束线自由度
    {
        SG::DataStructure::FEM::RBAR1Data rbar1;
        rbar1.m_id         = 5;
        rbar1.m_masterNode = 5;
        rbar1.m_slaveDOFs  =  SG::DataStructure::FEM::DofSet2Int ({ DOFDirections::DOF_Ux, DOFDirections::DOF_Uy, DOFDirections::DOF_Uz });
        rbar1.m_slaveNodes = 6;
        dbServiceFactory->get<IRBAR1Service> ()->Add  (rbar1);
        rbar1.m_id         = 5;
        rbar1.m_masterNode = 5;
        rbar1.m_slaveDOFs  =  SG::DataStructure::FEM::DofSet2Int ({ DOFDirections::DOF_Ux, DOFDirections::DOF_Uy, DOFDirections::DOF_Uz });
        rbar1.m_slaveNodes = 7;
        dbServiceFactory->get<IRBAR1Service> ()->Add  (rbar1);
        rbar1.m_id         = 5;
        rbar1.m_masterNode = 5;
        rbar1.m_slaveDOFs  =  SG::DataStructure::FEM::DofSet2Int ({ DOFDirections::DOF_Ux, DOFDirections::DOF_Uy, DOFDirections::DOF_Uz });
        rbar1.m_slaveNodes = 8;
        dbServiceFactory->get<IRBAR1Service> ()->Add  (rbar1);
    }
    // 节点固定约束
    {
        SG::DataStructure::FEM::SPCData spc;
        spc.m_sId     = 1;
        spc.m_g       = 1;
        spc.m_c = SG::DataStructure::FEM::DofSet2Int ({ DOFDirections::DOF_Ux, DOFDirections::DOF_Uy, DOFDirections::DOF_Uz });
        spc.m_d  = 0;
        dbServiceFactory->get<ISPCService> ()->Add (spc);
        spc.m_g       = 3;
        spc.m_c = SG::DataStructure::FEM::DofSet2Int ({ DOFDirections::DOF_Ux, DOFDirections::DOF_Uy });
        spc.m_d  = 0;
        dbServiceFactory->get<ISPCService> ()->Add (spc);
        spc.m_g       = 2;
        spc.m_c = SG::DataStructure::FEM::DofSet2Int ({ DOFDirections::DOF_Uz });
        spc.m_d  =0;
        dbServiceFactory->get<ISPCService> ()->Add (spc);
    }
}